package org.ne.springboot.utils.PaperHandleUtils.FontCheckUtils;

import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.ne.springboot.utils.PaperHandleUtils.CommonUtils.WordUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;

/**
 * @author wey
 * @date 2025/9/4 下午9:22 09
 * Word文档格式检查工具类（基于大连民族大学本科毕业设计规范）
 **/

@Slf4j
public class FontCheckUtils {

    // 标题文本到级别的映射
    private static final Map<String, Integer> TITLE_MAP = new HashMap<>();
    // 段落文本到格式信息的映射
    private static final Map<String, Map<String, Object>> fontMap = new HashMap<>();

    // 定义格式规范常量（根据文档要求）
    private static final String FONT_SONG = "宋体";
    private static final String FONT_TIMES_NEW_ROMAN = "Times New Roman";
    private static final String FONT_HEITI = "黑体";
    //论文大标题(三号对应约16磅)
    private static final float PAPER_TITLE_FONT_SIZE = 16.0f;
    // 章标题字号（小三对应约15磅）
    private static final float CHAPTER_TITLE_FONT_SIZE = 15.0f;
    // 节标题字号（四号对应约14磅）
    private static final float SECTION_TITLE_FONT_SIZE = 14.0f;
    // 一级标题字号（小四对应约12磅）
    private static final float SUBSECTION_TITLE_FONT_SIZE = 12.0f;
    // 正文字号（小四）
    private static final float NORMAL_TEXT_FONT_SIZE = 12.0f;
    // 图、表标注(五号)
    private static final float LITTLE_TITLE_OF_TABLE_AND_PICTURE = 10.5f;
    // 标题行间距（1.5倍）
    private static final float LINE_SPACING_TITLE = 1.5f;
    //文献引用间距（1.25倍）
    private static final float REFERENCE_SPACING_TITLE = 1.25f;

    // 正文行间距（固定值22磅）
    private static final float LINE_SPACING_NORMAL = 22.0f;
    // 首行缩进（2个汉字）
    private static final float FIRST_LINE_INDENT = 2.0f;
    // 章标题段后间距（11磅）
    private static final float CHAPTER_SPACING_AFTER = 11.0f;

    // 特殊段落标识
    private static final List<String> ABSTRACT_TITLES = Arrays.asList("摘要", "Abstract");
    private static final List<String> KEYWORD_TITLES = Arrays.asList("关键词", "Key Words");
    private static final List<String> CATALOG_TITLE = Collections.singletonList("目录");
    private static final List<String> REFERENCE_TITLE = Collections.singletonList("参考文献");
    private static final List<String> CONCLUSION_TITLE = Collections.singletonList("结论");
    private static final List<String> ACKNOWLEDGEMENT_TITLE = Collections.singletonList("致谢");

    // 加载标题信息
    private static void getTitles(MultipartFile file) throws IOException {
        // 存储标题及其级别信息
        List<Map<String, Object>> titles = WordUtils.extractTitles(file);
        for (Map<String, Object> tmp : titles) {
            TITLE_MAP.put(tmp.get("text").toString(), (Integer) tmp.get("level"));
        }
    }

    // 加载格式信息
    private static void getFonts(MultipartFile file) throws IOException {
        // 存储所有段落的格式信息
        List<Map<String, Object>> fonts = WordUtils.extractFormatInfo(file);
        for (Map<String, Object> tmp : fonts) {
            String paragraphText = tmp.get("paragraph_text").toString();
            fontMap.put(paragraphText, tmp);
        }
    }


    private static final List<Character> CHARS = Arrays.asList('。', '，','！','？','》','《','：','；','“','”','【','】','、','’','（','）');
    /**
     * 判断字符串是否包含中文
     * @param str 输入字符串
     * @return 是否包含中文
     */
    private static boolean containsChinese(String str) {
        if (str == null) {
            return false;
        }


        for (char c : str.toCharArray()) {
            if (Character.UnicodeBlock.of(c) == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || CHARS.contains(c)) {
                return true;
            }
        }
        return false;
    }

    private static String skipSpaces(String str) {
        if (str == null) {
            return null;
        }
        String[] words = str.split("\\s+");
        StringBuilder sb = new StringBuilder();
        for (String word : words) {

            sb.append(word);
        }
        return sb.toString();
    }

    /**
     * 执行文档格式检查并在原始文档中直接标红错误
     * @param file Word文档文件
     * @return 包含所有错误的映射（键为文本内容，值为错误列表）
     * @throws IOException 文件处理异常
     */
    public static Map<String, List<String>> fontCheck(OutputStream  markedDocStream, MultipartFile file) throws IOException {
        log.debug("开始格式检查，文件信息={}", file.getOriginalFilename());
        getTitles(file);
        getFonts(file);
        Map<String, List<String>> errorMap = new LinkedHashMap<>();

        try (InputStream is = file.getInputStream(); XWPFDocument document = new XWPFDocument(is)) {


            /*
             *
             *  0"大 连 民 族 大 学 本 科 毕 业 设 计（论 文）",
            1"基于Vue的垃圾分类微信小程序的设计与实现",
            2"学 院（系）： 计算机科学与工程学院",
            3"专       业： 计算机科学与技术",
            4"学 生 姓 名： 李牵",
            5"学       号： 2017037208",
            6"指 导 教 师： 逯波",
            7"评 阅 教 师：",
            8"完 成 日 期： 2021年5月",
            9"大连民族大学",
             *
             * */
            //跳过上述固定内容，直接从 “摘要” 开始检测
            boolean canHandle = false;
            for (int i = 0; i < document.getParagraphs().size(); i++) {
                XWPFParagraph paragraph = document.getParagraphs().get(i);

                String text = paragraph.getText().trim();
                String withoutSpace = skipSpaces(text);
                if (ABSTRACT_TITLES.contains(withoutSpace)) {
                    canHandle = true;
                }
                if (!canHandle) {
                    continue;
                }
                if (text.isEmpty()) {
                    continue;
                }

                Map<String, Object> font = fontMap.get(text);
                if (font == null) {
                    // 尝试处理可能存在的格式差异
                    for (String key : fontMap.keySet()) {
                        if (key.trim().equals(text)) {
                            font = fontMap.get(key);
                            break;
                        }
                    }
                    if (font == null) {
                        continue;
                    }
                }

                List<String> errors = new ArrayList<>();

                // 根据段落类型进行检查
                if (ABSTRACT_TITLES.contains(withoutSpace)) {
                    //摘要
                    errors = abstractCheck(text, font);
                } else if (KEYWORD_TITLES.contains(withoutSpace) ||
                        withoutSpace.startsWith("关键词") ||
                        withoutSpace.startsWith("Key")) {
                    errors = keywordCheck(text, font);
                } else if (CATALOG_TITLE.contains(withoutSpace)) {
                    //目录
                    errors = catalogCheck(text, font);
                    int t = i+1;
                    for (int j = t;j < document.getParagraphs().size(); j++) {
                        String catalogTitle = document.getParagraphs().get(j).getText();
                        String withoutSpaceCatalog = skipSpaces(catalogTitle);


                        List<String> errorsCatalog = catalogSubTitle(catalogTitle, fontMap.get(catalogTitle));
                        errors.addAll(errorsCatalog);
                        if (!errorsCatalog.isEmpty()) {
                            markErrorsInDocument(document.getParagraphs().get(j), errorsCatalog);
                            errorMap.put(catalogTitle, errorsCatalog);
                        }
                        if (withoutSpaceCatalog.contains(ACKNOWLEDGEMENT_TITLE.getFirst()) ) {
                            i=j;
                            break;
                        }


                    }

                } else if (CONCLUSION_TITLE.contains(withoutSpace)) {
                    //结论
                    errors = conclusionTitleCheck(text, font);
                } else if (ACKNOWLEDGEMENT_TITLE.contains(withoutSpace)) {
                    //致谢
                    errors = acknowledgementTitleCheck(text, font);
                } else if (REFERENCE_TITLE.contains(withoutSpace)) {
                    int t = i;
                    for (int j = t;j < document.getParagraphs().size(); j++) {
                        String reference = document.getParagraphs().get(j).getText();
                        String withoutSpaceReference = skipSpaces(reference);
                        if (withoutSpaceReference.isEmpty()) {
                            markErrorsInDocument(document.getParagraphs().get(j), errors);
                            continue;
                        }
                        if (ACKNOWLEDGEMENT_TITLE.contains(withoutSpaceReference)) {
                            i = j - 1;
                            break;
                        }
//                        System.out.println(reference);
                        Map<String, Object> referenceFontMap = fontMap.get(reference);
                        if (referenceFontMap == null) {
                            continue;
                        }
                        List<String> errorsReference = referenceContentCheck(reference, referenceFontMap);
                        errors.addAll(errorsReference);
                        if (ACKNOWLEDGEMENT_TITLE.contains(withoutSpaceReference)) {
                            i = j - 1;
                            break;
                        }
                    }


                } else if (TITLE_MAP.containsKey(text)) {
                    //各级标题
                    int level = TITLE_MAP.get(text);
                    if (level == 1) {
                        //章标题
                        errors = chapterTitleCheck(text, font);
                    } else if (level == 2) {
                        //节标题
                        errors = sectionTitleCheck(text, font);
                    } else {
                        //小节标题
                        errors = subsectionTitleCheck(text, font);
                    }
                } else {
                    //以上都不是，则为正文
                    errors = normalContentCheck(text, font);
                }

                // 如果有错误，在原始文档中直接标红
                if (!errors.isEmpty()) {
                    markErrorsInDocument(paragraph, errors);
                    errorMap.put(text, errors);
                }
            }

            document.write(markedDocStream);

        } catch (Exception e) {
            throw new IOException("文档格式检查失败: " + e.getMessage(), e);
        }

        return errorMap;
    }


    /**
     * 在文档中标记错误位置（直接在原始段落中标红）
     */
    private static void markErrorsInDocument(XWPFParagraph paragraph, List<String> errors) {
        // 保存原始文本
        String originalText = paragraph.getText();

        // 清除原有文本
        for (int i = paragraph.getRuns().size() - 1; i >= 0; i--) {
            paragraph.removeRun(i);
        }

        // 创建标红文本
        XWPFRun errorRun = paragraph.createRun();
        errorRun.setText(originalText);
        errorRun.setColor("FF0000");
        // 设置红色字体
        //errorRun.setBold(true);
        // 加粗显示
    }

    /*
    *   formatInfo内的格式为:
 {
            "after_spacing": 0.0,
            "line_spacing_rule": "Multiple",
            "background_color": "#000000",
            "paragraph_text": "大 连 民 族 大 学 本 科 毕 业 设 计（论 文）",
            "borders": {
                "right_color": "#000000",
                "top_style": "None",
                "left_color": "#000000",
                "left_style": "None",
                "right_width": 0.0,
                "top_width": 0.0,
                "bottom_style": "None",
                "right_style": "None",
                "bottom_width": 0.0,
                "top_color": "#000000",
                "left_width": 0.0,
                "bottom_color": "#000000"
            },
            "line_spacing": 15.0,
            "right_indent": 0.0,
            "alignment": "Center",
            "before_spacing": 0.0,
            "text_formats": [
                {
                    "underline": "None",
                    "font_size": 18.0,
                    "highlight_color": "#000000",
                    "sub_super_script": "None",
                    "bold": true,
                    "italic": false,
                    "font_name": "Times New Roman",
                    "text_background_color": "#000000",
                    "all_caps": false,
                    "text": "大 连 民 族 ",
                    "text_color": "#000000",
                    "strikethrough": false,
                    "is_small_caps": false
                },
                {
                    "underline": "None",
                    "font_size": 18.0,
                    "highlight_color": "#000000",
                    "sub_super_script": "None",
                    "bold": true,
                    "italic": false,
                    "font_name": "Times New Roman",
                    "text_background_color": "#000000",
                    "all_caps": false,
                    "text": "大 学",
                    "text_color": "#000000",
                    "strikethrough": false,
                    "is_small_caps": false
                },
                {
                    "underline": "None",
                    "font_size": 18.0,
                    "highlight_color": "#000000",
                    "sub_super_script": "None",
                    "bold": true,
                    "italic": false,
                    "font_name": "Times New Roman",
                    "text_background_color": "#000000",
                    "all_caps": false,
                    "text": " 本 科 毕 业 设 计（论 文）",
                    "text_color": "#000000",
                    "strikethrough": false,
                    "is_small_caps": false
                }
            ],
            "left_indent": 0.0,
            "first_line_indent": 0.0
        }
    *
    *
    *
    * */
    /**
     * 获取第一个文本的字体名称
     */
    private static String getFirstFontName(Map<String, Object> fontInfo) {
        if (fontInfo == null) {
            return null;
        }
        if (!fontInfo.containsKey("text_formats")) {
            return null;
        }
        List<Map<String, Object>> textFormats = (List<Map<String, Object>>) fontInfo.get("text_formats");
        if (textFormats != null && !textFormats.isEmpty()) {
            return (String) textFormats.getFirst().get("font_name");
        }
        return null;
    }

    /**
     * 获取第一个文本的字体大小
     */
    private static Float getFirstFontSize(Map<String, Object> fontInfo) {
        if (fontInfo == null) {
            return null;
        }
        if (!fontInfo.containsKey("text_formats")) {
            return null;
        }
        List<Map<String, Object>> textFormats = (List<Map<String, Object>>) fontInfo.get("text_formats");
        if (textFormats != null && !textFormats.isEmpty()) {
            return (Float) textFormats.getFirst().get("font_size");
        }
        return null;
    }

    /**
     * 获取第一个文本的加粗状态
     */
    private static Boolean getFirstBold(Map<String, Object> fontInfo) {
        if (fontInfo == null) {
            return null;
        }
        if (!fontInfo.containsKey("text_formats")) {
            return null;
        }
        List<Map<String, Object>> textFormats = (List<Map<String, Object>>) fontInfo.get("text_formats");
        if (textFormats != null && !textFormats.isEmpty()) {
            return (Boolean) textFormats.getFirst().get("bold");
        }
        return null;
    }
    private static List<String> abstractCheck(String text, Map<String, Object> font) {
        List<String> errors = new ArrayList<>();

        // 1. 检查标题级别
        Integer level = TITLE_MAP.get(text);
        if (level == null || level != 1) {
            errors.add("摘要格式错误：应为 1级标题, 实际为 " + (level != null ? level : "未知") + "级标题");
        }

        // 2. 检查字体
        String fontName = getFirstFontName(font);
        if (!FONT_HEITI.equals(fontName)) {
            errors.add("摘要字体错误：应为 " + FONT_HEITI + ", 实际为 " + fontName);
        }

        // 3. 检查字号
        Float fontSize = getFirstFontSize(font);
        if (fontSize == null || fontSize < CHAPTER_TITLE_FONT_SIZE) {
            errors.add("摘要字号错误：应不小于" + CHAPTER_TITLE_FONT_SIZE + "磅（小三）, 实际为 " + fontSize);
        }

        // 4. 检查对齐方式
        String alignment = (String) font.get("alignment");
        if (!"Center".equals(alignment)) {
            errors.add("摘要对齐方式错误：应为居中, 实际为 " + alignment);
        }



        // 6. 检查行间距值
        Float lineSpacing = (Float) font.get("line_spacing");
        if (lineSpacing == null || lineSpacing < LINE_SPACING_TITLE) {
            errors.add("摘要行间距错误：应不小于1.5倍, 实际为 " + lineSpacing);
        }

        // 7. 检查段后间距
        Float afterSpacing = (Float) font.get("after_spacing");
        if (afterSpacing == null || afterSpacing < CHAPTER_SPACING_AFTER) {
            errors.add("摘要段后间距错误：应不小于11磅, 实际为 " + afterSpacing);
        }

        // 8. 检查段前间距
        Float beforeSpacing = (Float) font.get("before_spacing");
        if (beforeSpacing == null || beforeSpacing != 0) {
            errors.add("摘要段前间距错误：应为0磅, 实际为 " + beforeSpacing);
        }

        return errors;
    }


    private static List<String> keywordCheck(String text, Map<String, Object> font) {
        List<String> errors = new ArrayList<>();

        // 1. 检查是否为关键词标题
        boolean isChineseKeyword = text.contains("关键词");
        boolean isEnglishKeyword = text.contains("Key Words") || text.contains("Keywords");

        if (!isChineseKeyword && !isEnglishKeyword) {
            errors.add("关键词格式错误：应包含'关键词'或'Key Words'标识");
            return errors; // 如果不是关键词部分，直接返回错误
        }

        // 2. 检查字体
        String fontName = getFirstFontName(font);
        if (isChineseKeyword && !FONT_HEITI.equals(fontName)) {
            errors.add("关键词字体错误：应为" + FONT_HEITI + "，实际为" + fontName);
        } else if (isEnglishKeyword && !FONT_TIMES_NEW_ROMAN.equals(fontName)) {
            errors.add("关键词字体错误：应为" + FONT_TIMES_NEW_ROMAN + "，实际为" + fontName);
        }

        // 3. 检查字号
        Float fontSize = getFirstFontSize(font);
        if (fontSize == null || fontSize < SUBSECTION_TITLE_FONT_SIZE) {
            errors.add("关键词字号错误：应不小于" + SUBSECTION_TITLE_FONT_SIZE + "磅（小四），实际为" + fontSize);
        }

        // 4. 检查加粗状态
        Boolean isBold = getFirstBold(font);
        if (isBold == null || !isBold) {
            errors.add("关键词加粗状态错误：应加粗");
        }

        // 5. 检查关键词分隔符
        if (!text.contains("；") && !text.contains(";")) {
            errors.add("关键词分隔符错误：应用分号分隔关键词");
        }

        // 6. 检查关键词数量
        int keywordCount = countKeywords(text);
        if (isChineseKeyword && (keywordCount < 3 || keywordCount > 5)) {
            errors.add("关键词数量错误：应为3-5个，实际为" + keywordCount);
        } else if (isEnglishKeyword && (keywordCount < 3 || keywordCount > 8)) {
            errors.add("关键词数量错误：应为3-8个，实际为" + keywordCount);
        }

        // 7. 检查末尾标点
        if (text.endsWith("。") || text.endsWith(".") || text.endsWith("；") || text.endsWith(";")) {
            errors.add("关键词格式错误：末尾不应加标点符号");
        }

        // 8. 检查关键词格式（中英文对应）
        if ((isChineseKeyword && text.contains(":") )|| (isEnglishKeyword && text.contains("："))) {
            errors.add("关键词格式错误：中英文标点符号混用");
        }

        return errors;
    }

    /**
     * 统计关键词数量
     */
    private static int countKeywords(String text) {
        // 中文关键词计数
        if (text.contains("关键词")) {
            String keywordPart = text.substring(text.indexOf("关键词") + 3).trim();
            return keywordPart.split("[；;]").length;
        }
        // 英文关键词计数
        else if (text.contains("Key Words")) {
            String keywordPart = text.substring(text.indexOf("Key Words") + 9).trim();
            return keywordPart.split("[;]").length;
        }
        return 0;
    }


    private static List<String> normalContentCheck(String text, Map<String, Object> font) {
        List<String> errors = new ArrayList<>();


        if(text.length() <= 100 && !containsChinese(text)) {
            //英文标题
            String fontName = getFirstFontName(font);
            Float fontSize = getFirstFontSize(font);
            if (fontSize != PAPER_TITLE_FONT_SIZE) {
                errors.add("英文标题字号错误， 应为 三号 实际为" + fontSize);
            }
            if (fontName != null && !fontName.equals(FONT_TIMES_NEW_ROMAN)) {
                errors.add("英文标题字体错误，应为" +FONT_TIMES_NEW_ROMAN +"实际为"+fontName);
            }
            return errors;
        }

        if(text.length() <= 100 && text.startsWith("图") || text.startsWith("表")) {
            String fontName = getFirstFontName(font);
            Float fontSize = getFirstFontSize(font);
            if (fontSize != LITTLE_TITLE_OF_TABLE_AND_PICTURE) {
                errors.add("图表标注字号错误， 应为 五号 实际为" + fontSize);
            }
            if (fontName != null && !fontName.equals(FONT_SONG)) {
                errors.add("图表字体错误， 应为 "+FONT_SONG+" 实际为" + fontName);
            }
            return errors;
        }


        // 1. 检查首行缩进
        Float firstLineIndent = (Float) font.get("first_line_indent");
        if (firstLineIndent == null || firstLineIndent < FIRST_LINE_INDENT) {
            errors.add("正文首行缩进错误：应不小于2个汉字，实际为" + firstLineIndent);
        }

        // 2. 检查行距
        Float lineSpacing = (Float) font.get("line_spacing");
        if (lineSpacing == null || lineSpacing < LINE_SPACING_NORMAL) {
            errors.add("正文行距错误：应不小于22磅，实际为" + lineSpacing);
        }

        // 3. 检查行距规则
        String lineSpacingRule = (String) font.get("line_spacing_rule");
        if (!"Exactly".equals(lineSpacingRule)) {
            errors.add("正文行距规则错误：应为固定值，实际为" + lineSpacingRule);
        }

        // 4. 检查段前段后间距
        Float beforeSpacing = (Float) font.get("before_spacing");
        Float afterSpacing = (Float) font.get("after_spacing");
        if (beforeSpacing == null || beforeSpacing != 0) {
            errors.add("正文段前间距错误：应为0行，实际为" + beforeSpacing);
        }
        if (afterSpacing == null || afterSpacing != 0) {
            errors.add("正文段后间距错误：应为0行，实际为" + afterSpacing);
        }

        // 5. 获取文本格式信息
        List<Map<String, Object>> textFormats = (List<Map<String, Object>>) font.get("text_formats");
        if (textFormats == null || textFormats.isEmpty()) {
            errors.add("正文格式错误：缺少文本格式信息");
            return errors;
        }

        // 6. 检查混合文本格式
        boolean hasChinese = containsChinese(text);

        for (Map<String, Object> textFormat : textFormats) {
//            System.out.println(textFormat);
            String content = (String) textFormat.get("text");
            String fontName = (String) textFormat.get("font_name");
            Float fontSize = (Float) textFormat.get("font_size");
            Boolean isBold = (Boolean) textFormat.get("bold");
            Boolean isItalic = (Boolean) textFormat.get("italic");

            // 跳过空文本
            if (content.trim().isEmpty()) {
                continue;
            }

            // 7. 检查中英文字体
            boolean isChinesePart = containsChinese(content) || CHARS.contains(content.charAt(0));
            if (hasChinese && isChinesePart && !FONT_SONG.equals(fontName)) {
                errors.add("错误字段：'"+ content +"' 中文内容字体错误：应为" + FONT_SONG + "，实际为" + fontName);
            } else if (hasChinese && !isChinesePart && !FONT_TIMES_NEW_ROMAN.equals(fontName)) {
                errors.add("错误字段：'"+ content +"' 英文内容字体错误：应为" + FONT_TIMES_NEW_ROMAN + "，实际为" + fontName);
            } else if (!hasChinese && !FONT_TIMES_NEW_ROMAN.equals(fontName)) {
                errors.add("错误字段：'"+ content +"' 英文正文字体错误：应为" + FONT_TIMES_NEW_ROMAN + "，实际为" + fontName);
            }

            // 8. 检查字号
            if (fontSize == null || fontSize < NORMAL_TEXT_FONT_SIZE) {
                errors.add("错误字段：'"+ content +"' 正文字号错误：应不小于" + NORMAL_TEXT_FONT_SIZE + "磅，实际为" + fontSize);
            }

            // 9. 检查加粗和斜体
            if (isBold != null && isBold) {
                errors.add("错误字段：'"+ content +"' 正文格式错误：不应加粗");
            }
            if (isItalic != null && isItalic) {
                errors.add("错误字段：'"+ content +"' 正文格式错误：不应斜体");
            }

            // 10. 检查网格对齐选项
            String gridAlignment = (String) textFormat.get("grid_alignment");
            if (gridAlignment != null && !"None".equals(gridAlignment)) {
                errors.add("错误字段：'"+ content +"' 正文格式错误：应取消网格对齐选项");
            }
        }

        return errors;
    }

    /**
     * 检查目录主标题格式
     * 要求：字体-黑体，字号-小三
     */
    private static List<String> catalogCheck(String text, Map<String, Object> font) {
        List<String> errors = new ArrayList<>();

        // 1. 检查字体

        String fontName = getFirstFontName(font);
        if (!FONT_HEITI.equals(fontName)) {
            errors.add("目录标题字体错误：应为" + FONT_HEITI + "，实际为" + fontName);
        }

        // 2. 检查字号
        Float fontSize = getFirstFontSize(font);
        if (fontSize == null || fontSize < CHAPTER_TITLE_FONT_SIZE) {
            errors.add("目录标题字号错误：应不小于" + CHAPTER_TITLE_FONT_SIZE + "磅（小三），实际为" + fontSize);
        }

        // 3. 检查对齐方式
        String alignment = (String) font.get("alignment");
        if (!"Center".equals(alignment)) {
            errors.add("目录标题对齐方式错误：应为居中，实际为" + alignment);
        }


        return errors;
    }

    /**
     * 检查目录中子标题和页码格式
     * 要求：字体-宋体，字号-小四
     */
    private static List<String> catalogSubTitle(String text, Map<String, Object> font) {
        List<String> errors = new ArrayList<>();

//         1. 检查字体
//        String fontName = getFirstFontName(font);
//        if (!FONT_SONG.equals(fontName)) {
//            errors.add("目录内容字体错误：应为" + FONT_SONG + "，实际为" + fontName);
//        }

        // 2. 检查字号
        Float fontSize = getFirstFontSize(font);
        if (fontSize == null || fontSize < SUBSECTION_TITLE_FONT_SIZE) {
            errors.add("目录内容字号错误：应不小于" + SUBSECTION_TITLE_FONT_SIZE + "磅（小四），实际为" + fontSize);
        }

        // 4. 检查缩进（根据标题级别应有不同的缩进）
        Float leftIndent = (Float) font.get("left_indent");
        if (leftIndent == null) {
            errors.add("目录内容缩进错误：应设置适当缩进");
        }


        return errors;
    }




    /**
     * 检查章标题格式（如：第五章题目）
     * 要求：黑体，小三，1.5倍行距，段后11磅
     */
    private static List<String> chapterTitleCheck(String text, Map<String, Object> font) {
        List<String> errors = new ArrayList<>();

        // 1. 检查字体
        String fontName = getFirstFontName(font);
        if (!FONT_HEITI.equals(fontName)) {
            errors.add("章标题字体错误：应为" + FONT_HEITI + "，实际为" + fontName);
        }

        // 2. 检查字号
        Float fontSize = getFirstFontSize(font);
        if (fontSize == null || fontSize < CHAPTER_TITLE_FONT_SIZE) {
            errors.add("章标题字号错误：应不小于" + CHAPTER_TITLE_FONT_SIZE + "磅（小三），实际为" + fontSize);
        }

        // 3. 检查行间距
        Float lineSpacing = (Float) font.get("line_spacing");
        if (lineSpacing == null || lineSpacing < LINE_SPACING_TITLE) {
            errors.add("章标题行距错误：应不小于1.5倍，实际为" + lineSpacing);
        }

        // 4. 检查行间距规则
        String lineSpacingRule = (String) font.get("line_spacing_rule");
        if (!"Multiple".equals(lineSpacingRule)) {
            errors.add("章标题行距规则错误：应为多倍行距，实际为" + lineSpacingRule);
        }

        // 5. 检查段后间距
        Float afterSpacing = (Float) font.get("after_spacing");
        if (afterSpacing == null || afterSpacing < CHAPTER_SPACING_AFTER) {
            errors.add("章标题段后间距错误：应不小于11磅，实际为" + afterSpacing);
        }

        // 6. 检查段前间距
        Float beforeSpacing = (Float) font.get("before_spacing");
        if (beforeSpacing == null || beforeSpacing != 0) {
            errors.add("章标题段前间距错误：应为0磅，实际为" + beforeSpacing);
        }


        return errors;
    }

    /**
     * 检查节标题格式（如：5.1 第五章第一节题目）
     * 要求：黑体，四号，1.5倍行距，段前0.5行
     */
    private static List<String> sectionTitleCheck(String text, Map<String, Object> font) {
        List<String> errors = new ArrayList<>();

        // 1. 检查字体
        String fontName = getFirstFontName(font);
        if (!FONT_HEITI.equals(fontName)) {
            errors.add("节标题字体错误：应为" + FONT_HEITI + "，实际为" + fontName);
        }

        // 2. 检查字号
        Float fontSize = getFirstFontSize(font);
        if (fontSize == null || fontSize < SECTION_TITLE_FONT_SIZE) {
            errors.add("节标题字号错误：应不小于" + SECTION_TITLE_FONT_SIZE + "磅（四号），实际为" + fontSize);
        }

        // 3. 检查行间距
        Float lineSpacing = (Float) font.get("line_spacing");
        if (lineSpacing == null || lineSpacing < LINE_SPACING_TITLE) {
            errors.add("节标题行距错误：应不小于1.5倍，实际为" + lineSpacing);
        }

        // 4. 检查段前间距
        Float beforeSpacing = (Float) font.get("before_spacing");
        if (beforeSpacing == null || beforeSpacing < 0.5f) {
            errors.add("节标题段前间距错误：应不小于0.5行，实际为" + beforeSpacing);
        }

        // 5. 检查段后间距
        Float afterSpacing = (Float) font.get("after_spacing");
        if (afterSpacing == null || afterSpacing != 0) {
            errors.add("节标题段后间距错误：应为0行，实际为" + afterSpacing);
        }


        return errors;
    }

    /**
     * 检查小节标题格式（如：5.1.1第五章第一节一级题目）
     * 要求：黑体，小四，1.5倍行距，段前0.5行
     */
    private static List<String> subsectionTitleCheck(String text, Map<String, Object> font) {
        List<String> errors = new ArrayList<>();

        // 1. 检查字体
        String fontName = getFirstFontName(font);
        if (!FONT_HEITI.equals(fontName)) {
            errors.add("小节标题字体错误：应为" + FONT_HEITI + "，实际为" + fontName);
        }

        // 2. 检查字号
        Float fontSize = getFirstFontSize(font);
        if (fontSize == null || fontSize < SUBSECTION_TITLE_FONT_SIZE) {
            errors.add("小节标题字号错误：应不小于" + SUBSECTION_TITLE_FONT_SIZE + "磅（小四），实际为" + fontSize);
        }

        // 3. 检查行间距
        Float lineSpacing = (Float) font.get("line_spacing");
        if (lineSpacing == null || lineSpacing < LINE_SPACING_TITLE) {
            errors.add("小节标题行距错误：应不小于1.5倍，实际为" + lineSpacing);
        }

        // 4. 检查段前间距
        Float beforeSpacing = (Float) font.get("before_spacing");
        if (beforeSpacing == null || beforeSpacing < 0.5f) {
            errors.add("小节标题段前间距错误：应不小于0.5行，实际为" + beforeSpacing);
        }

        // 5. 检查段后间距
        Float afterSpacing = (Float) font.get("after_spacing");
        if (afterSpacing == null || afterSpacing != 0) {
            errors.add("小节标题段后间距错误：应为0行，实际为" + afterSpacing);
        }


        return errors;
    }

    /**
     * 检查结论标题格式
     * 要求：黑体，居中，小三，1.5倍行距，段后11磅，段前为0
     */
    private static List<String> conclusionTitleCheck(String text, Map<String, Object> font) {
        List<String> errors = new ArrayList<>();

        // 1. 检查字体
        String fontName = getFirstFontName(font);
        if (!FONT_HEITI.equals(fontName)) {
            errors.add("结论标题字体错误：应为" + FONT_HEITI + "，实际为" + fontName);
        }

        // 2. 检查字号
        Float fontSize = getFirstFontSize(font);
        if (fontSize == null || fontSize < CHAPTER_TITLE_FONT_SIZE) {
            errors.add("结论标题字号错误：应不小于" + CHAPTER_TITLE_FONT_SIZE + "磅（小三），实际为" + fontSize);
        }

        // 3. 检查对齐方式
        String alignment = (String) font.get("alignment");
        if (!"Center".equals(alignment)) {
            errors.add("结论标题对齐方式错误：应为居中，实际为" + alignment);
        }

        // 4. 检查行间距
        Float lineSpacing = (Float) font.get("line_spacing");
        if (lineSpacing == null || lineSpacing < LINE_SPACING_TITLE) {
            errors.add("结论标题行距错误：应不小于1.5倍，实际为" + lineSpacing);
        }

        // 5. 检查段后间距
        Float afterSpacing = (Float) font.get("after_spacing");
        if (afterSpacing == null || afterSpacing < CHAPTER_SPACING_AFTER) {
            errors.add("结论标题段后间距错误：应不小于11磅，实际为" + afterSpacing);
        }

        // 6. 检查段前间距
        Float beforeSpacing = (Float) font.get("before_spacing");
        if (beforeSpacing == null || beforeSpacing != 0) {
            errors.add("结论标题段前间距错误：应为0磅，实际为" + beforeSpacing);
        }




        return errors;
    }

    /**
     * 检查致谢标题格式
     * 要求：黑体，居中，小三，1.5倍行距，段后11磅，段前为0
     * @param text 标题文本
     * @param font 格式信息
     * @return 错误列表
     */
    private static List<String> acknowledgementTitleCheck(String text, Map<String, Object> font) {
        List<String> errors = new ArrayList<>();


        // 2. 检查字体
        String fontName = getFirstFontName(font);
        if (!FONT_HEITI.equals(fontName)) {
            errors.add("致谢标题字体错误：应为" + FONT_HEITI + "，实际为" + fontName);
        }

        // 3. 检查字号
        Float fontSize = getFirstFontSize(font);
        if (fontSize == null || fontSize < CHAPTER_TITLE_FONT_SIZE) {
            errors.add("致谢标题字号错误：应不小于" + CHAPTER_TITLE_FONT_SIZE + "磅（小三），实际为" + fontSize);
        }

        // 4. 检查对齐方式
        String alignment = (String) font.get("alignment");
        if (!"Center".equals(alignment)) {
            errors.add("致谢标题对齐方式错误：应为居中，实际为" + alignment);
        }

        // 5. 检查行间距
        Float lineSpacing = (Float) font.get("line_spacing");
        if (lineSpacing == null || lineSpacing < LINE_SPACING_TITLE) {
            errors.add("致谢标题行距错误：应不小于1.5倍，实际为" + lineSpacing);
        }

        // 6. 检查行间距规则
        String lineSpacingRule = (String) font.get("line_spacing_rule");
        if (!"Multiple".equals(lineSpacingRule)) {
            errors.add("致谢标题行距规则错误：应为多倍行距，实际为" + lineSpacingRule);
        }

        // 7. 检查段后间距
        Float afterSpacing = (Float) font.get("after_spacing");
        if (afterSpacing == null || afterSpacing < CHAPTER_SPACING_AFTER) {
            errors.add("致谢标题段后间距错误：应不小于11磅，实际为" + afterSpacing);
        }

        // 8. 检查段前间距
        Float beforeSpacing = (Float) font.get("before_spacing");
        if (beforeSpacing == null || beforeSpacing != 0) {
            errors.add("致谢标题段前间距错误：应为0磅，实际为" + beforeSpacing);
        }

        return errors;
    }


    private static List<String> referenceContentCheck(String text, Map<String, Object> font) {
        List<String> errors = new ArrayList<>();
        // 参考文献内容设置成字体：宋体，居中，字号：五号，多倍行距1.25，段前、段后均为0，取消网格对齐选项。
        String fontName = getFirstFontName(font);
        if (!FONT_SONG.equals(fontName)) {
            errors.add("参考文献字体错误：应为宋体，实际为" + fontName);
            // 补充错误信息
        }
        Float fontSize = getFirstFontSize(font);
        if (fontSize == null || fontSize < LITTLE_TITLE_OF_TABLE_AND_PICTURE) {
            errors.add("参考文献字号错误：应不小于" + LITTLE_TITLE_OF_TABLE_AND_PICTURE + "，当前为" + fontSize);
            // 补充错误信息
        }
        String alignment = (String) font.get("alignment");
        if (!"Center".equals(alignment)) {
            errors.add("参考文献对齐方式错误：应为居中，实际为" + alignment);
            // 补充错误信息
        }
        Float lineSpacing = (Float) font.get("line_spacing");
        if (lineSpacing == null || lineSpacing < REFERENCE_SPACING_TITLE) {
            errors.add("参考文献行距错误：应不小于" + REFERENCE_SPACING_TITLE + "，当前为" + lineSpacing);
        }
        Float afterSpacing = (Float) font.get("after_spacing");
        if (afterSpacing == null || afterSpacing != 0) {
            errors.add("参考文献段后间距错误：应为0，实际为" + afterSpacing);
        }
        Float beforeSpacing = (Float) font.get("before_spacing");
        if (beforeSpacing == null || beforeSpacing != 0) {
            errors.add("参考文献段前间距错误：应为0，实际为" + beforeSpacing);
        }
        String lineSpacingRule = (String) font.get("line_spacing_rule");
        if (!"Multiple".equals(lineSpacingRule)) {
            errors.add("参考文献行距规则错误：应为多倍行距，实际为" + lineSpacingRule);
        }
        return errors;
    }


}